#include "XModel.h"

;CXModel::CXModel(EModelType _eType) : CBaseModel(_eType)
{
	m_pMesh = NULL;
	m_pMeshMaterials = NULL;
	m_pMeshTextures = NULL;
	m_dwNumMaterials = 0;
}

CXModel::~CXModel()
{
	if(GetLoaded())
		Unload();
}

//////////////////////////////////////////////////////////////////////////
// X Mesh Loading Method
bool CXModel::Load(string _szModelName, IDirect3DDevice9* _pDev)
{
	LPD3DXBUFFER pD3DXMtrlBuffer;

	HRESULT _Error = S_OK;
	
	string _szModelPath = PH_ASSET_PATH + PH_MODELS_PATH + "X/" + _szModelName;
	string _FolderPath = _szModelPath.substr(0, _szModelPath.find_last_of("/") + 1);

	// Load the mesh from the specified file
	_Error = D3DXLoadMeshFromX(_szModelPath.c_str(), D3DXMESH_SYSTEMMEM, _pDev, NULL, &pD3DXMtrlBuffer, NULL, &m_dwNumMaterials, &m_pMesh);

	if(D3D_OK != _Error)
	{
		string _szError = "Could Not Find: " + _szModelName;
		MessageBox(NULL, _szError.c_str(), "XModel Error", MB_OK);
		return false;
	}

	// We need to extract the material properties and texture names from the pD3DXMtrlBuffer
	D3DXMATERIAL* phxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
	m_pMeshMaterials = new D3DMATERIAL9[m_dwNumMaterials];
	m_pMeshTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];

	if(!m_pMeshMaterials || !m_pMeshTextures)	
	{
		MessageBox(NULL, "System Out Of Memory!", "XModel Error", MB_OK);
		return false;
	}

	int _nNumMaterials = m_dwNumMaterials;
	for(int i = 0; i < _nNumMaterials; i++)
	{
		// Copy the material
		m_pMeshMaterials[i] = phxMaterials[i].MatD3D;

		// Set the ambient color for the material (D3DX does not do this)
		m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;

		m_pMeshTextures[i] = NULL;
		
		if(phxMaterials[i].pTextureFilename && (lstrlenA(phxMaterials[i].pTextureFilename) > 0))
		{
			// Create the texture
			_Error = D3DXCreateTextureFromFileA(_pDev, phxMaterials[i].pTextureFilename, &m_pMeshTextures[i]);
			
			if(D3D_OK != _Error)
			{
				// If texture is not in current folder, try parent folder
				const CHAR* strPrefix = _FolderPath.c_str();
				CHAR strTexture[MAX_PATH];
				strcpy_s( strTexture, MAX_PATH, strPrefix );
				strcat_s( strTexture, MAX_PATH, phxMaterials[i].pTextureFilename );
				// If texture is not in current folder, try parent folder
				_Error = D3DXCreateTextureFromFileA( _pDev, strTexture, &m_pMeshTextures[i]);
				
				if(D3D_OK != _Error)
				{
					MessageBox( NULL, "Could Not Find Texture Map.", "XModel Error", MB_OK);
					--m_dwNumMaterials;
				}
			}
		}
	}

	// Done with the material buffer
	pD3DXMtrlBuffer->Release();

	SetNumVerts(m_pMesh->GetNumVertices());
	SetNumTris(m_pMesh->GetNumFaces());
	SetName(_szModelName);
	SetPath(_szModelPath);
	SetNameLength(_szModelName.length());
	SetLoaded(true);

	return true;
}

//////////////////////////////////////////////////////////////////////////
// Unloads all attributes
bool CXModel::Unload(bool _bReloading)
{
	if(m_pMeshMaterials)
		delete[] m_pMeshMaterials;

	if(m_pMeshTextures)
	{
		for(DWORD i = 0; i < m_dwNumMaterials; i++)
		{
			if(m_pMeshTextures[i])
				m_pMeshTextures[i]->Release();
		}
		delete[] m_pMeshTextures;
	}

	if(m_pMesh)
		m_pMesh->Release();

	CBaseModel::Unload(_bReloading);
	
	return true;
}